using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Haoliang.Data.Entities;
using Haoliang.Models.System;
using Haoliang.Models.User;

namespace Haoliang.Data
{
    public static class DataSeeder
    {
        public static async Task SeedDataAsync(IServiceProvider serviceProvider)
        {
            using (var scope = serviceProvider.CreateScope())
            {
                var context = scope.ServiceProvider.GetRequiredService<CNCBusinessDbContext>();
                var logger = scope.ServiceProvider.GetService<Microsoft.Extensions.Logging.ILogger<DataSeeder>>();

                try
                {
                    logger.LogInformation("Starting database seed process...");

                    // Apply any pending migrations
                    await context.Database.MigrateAsync();

                    // Seed roles
                    await SeedRolesAsync(context);

                    // Seed users
                    await SeedUsersAsync(context);

                    // Seed permissions
                    await SeedPermissionsAsync(context);

                    // seed system configurations
                    await SeedSystemConfigsAsync(context);

                    // seed alarm rules
                    await SeedAlarmRulesAsync(context);

                    // seed device templates
                    await SeedDeviceTemplatesAsync(context);

                    logger.LogInformation("Database seed process completed successfully.");
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "Error occurred during database seed process.");
                    throw;
                }
            }
        }

        private static async Task SeedRolesAsync(CNCBusinessDbContext context)
        {
            if (!await context.Roles.AnyAsync())
            {
                var roles = new List<Role>
                {
                    new Role
                    {
                        RoleName = "Administrator",
                        Description = "System administrators with full access",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new Role
                    {
                        RoleName = "Manager",
                        Description = "Department managers with access to reporting and device management",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new Role
                    {
                        RoleName = "Operator",
                        Description = "Device operators with access to daily operations",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new Role
                    {
                        RoleName = "Viewer",
                        Description = "Read-only access to system data",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    }
                };

                await context.Roles.AddRangeAsync(roles);
                await context.SaveChangesAsync();
            }
        }

        private static async Task SeedUsersAsync(CNCBusinessDbContext context)
        {
            if (!await context.Users.AnyAsync())
            {
                // Create default admin user
                var adminRole = await context.Roles.FirstOrDefaultAsync(r => r.RoleName == "Administrator");
                if (adminRole != null)
                {
                    var adminUser = new User
                    {
                        Username = "admin",
                        Email = "admin@cncsystem.com",
                        PasswordHash = BCrypt.Net.BCrypt.HashPassword("Admin@123"),
                        FirstName = "System",
                        LastName = "Administrator",
                        RoleId = adminRole.RoleId,
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    };

                    await context.Users.AddAsync(adminUser);
                    await context.SaveChangesAsync();
                }

                // Create default manager user
                var managerRole = await context.Roles.FirstOrDefaultAsync(r => r.RoleName == "Manager");
                if (managerRole != null)
                {
                    var managerUser = new User
                    {
                        Username = "manager",
                        Email = "manager@cncsystem.com",
                        PasswordHash = BCrypt.Net.BCrypt.HashPassword("Manager@123"),
                        FirstName = "John",
                        LastName = "Doe",
                        Department = "Production",
                        RoleId = managerRole.RoleId,
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    };

                    await context.Users.AddAsync(managerUser);
                    await context.SaveChangesAsync();
                }

                // Create default operator user
                var operatorRole = await context.Roles.FirstOrDefaultAsync(r => r.RoleName == "Operator");
                if (operatorRole != null)
                {
                    var operatorUser = new User
                    {
                        Username = "operator",
                        Email = "operator@cncsystem.com",
                        PasswordHash = BCrypt.Net.BCrypt.HashPassword("Operator@123"),
                        FirstName = "Jane",
                        LastName = "Smith",
                        Department = "Production",
                        RoleId = operatorRole.RoleId,
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    };

                    await context.Users.AddAsync(operatorUser);
                    await context.SaveChangesAsync();
                }
            }
        }

        private static async Task SeedPermissionsAsync(CNCBusinessDbContext context)
        {
            if (!await context.Permissions.AnyAsync())
            {
                var permissions = new List<Permission>
                {
                    // Device Management
                    new Permission { PermissionName = "devices.create", Description = "Create new devices", Category = "Device" },
                    new Permission { PermissionName = "devices.read", Description = "View device information", Category = "Device" },
                    new Permission { PermissionName = "devices.update", Description = "Update device information", Category = "Device" },
                    new Permission { PermissionName = "devices.delete", Description = "Delete devices", Category = "Device" },
                    new Permission { PermissionName = "devices.control", Description = "Control device operations", Category = "Device" },

                    // Production Management
                    new Permission { PermissionName = "production.create", Description = "Create production records", Category = "Production" },
                    new Permission { PermissionName = "production.read", Description = "View production data", Category = "Production" },
                    new Permission { PermissionName = "production.update", Description = "Update production records", Category = "Production" },
                    new Permission { PermissionName = "production.delete", Description = "Delete production records", Category = "Production" },
                    new Permission { PermissionName = "production.analyze", Description = "Analyze production data", Category = "Production" },

                    // Alarm Management
                    new Permission { PermissionName = "alarms.create", Description = "Create alarms", Category = "Alarm" },
                    new Permission { PermissionName = "alarms.read", Description = "View alarms", Category = "Alarm" },
                    new Permission { PermissionName = "alarms.update", Description = "Update alarms", Category = "Alarm" },
                    new Permission { PermissionName = "alarms.delete", Description = "Delete alarms", Category = "Alarm" },
                    new Permission { PermissionName = "alarms.resolve", Description = "Resolve alarms", Category = "Alarm" },

                    // Template Management
                    new Permission { PermissionName = "templates.create", Description = "Create templates", Category = "Template" },
                    new Permission { PermissionName = "templates.read", Description = "View templates", Category = "Template" },
                    new Permission { PermissionName = "templates.update", Description = "Update templates", Category = "Template" },
                    new Permission { PermissionName = "templates.delete", Description = "Delete templates", Category = "Template" },

                    // System Management
                    new Permission { PermissionName = "system.config", Description = "Manage system configuration", Category = "System" },
                    new Permission { PermissionName = "system.logs", Description = "View system logs", Category = "System" },
                    new Permission { PermissionName = "system.users", Description = "Manage users", Category = "System" },
                    new Permission { PermissionName = "system.roles", Description = "Manage roles", Category = "System" },
                    new Permission { PermissionName = "system.backup", Description = "System backup operations", Category = "System" },

                    // Real-time Monitoring
                    new Permission { PermissionName = "monitoring.live", Description = "View real-time monitoring", Category = "Monitoring" },
                    new Permission { PermissionName = "monitoring.history", Description = "View monitoring history", Category = "Monitoring" },
                    new Permission { PermissionName = "monitoring.export", Description = "Export monitoring data", Category = "Monitoring" },

                    // Reports
                    new Permission { PermissionName = "reports.generate", Description = "Generate reports", Category = "Reporting" },
                    new Permission { PermissionName = "reports.view", Description = "View reports", Category = "Reporting" },
                    new Permission { PermissionName = "reports.export", Description = "Export reports", Category = "Reporting" },

                    // API Access
                    new Permission { PermissionName = "api.access", Description = "Access API endpoints", Category = "API" },
                    new Permission { PermissionName = "api.admin", Description = "Admin API access", Category = "API" }
                };

                await context.Permissions.AddRangeAsync(permissions);
                await context.SaveChangesAsync();
            }
        }

        private static async Task SeedSystemConfigsAsync(CNCBusinessDbContext context)
        {
            if (!await context.SystemConfigs.AnyAsync())
            {
                var configs = new List<SystemConfig>
                {
                    // Application Settings
                    new SystemConfig
                    {
                        ConfigKey = "app.name",
                        ConfigValue = "CNC Machine Monitoring System",
                        Description = "Application name",
                        Category = "Application",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "app.version",
                        ConfigValue = "1.0.0",
                        Description = "Application version",
                        Category = "Application",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },

                    // Collection Settings
                    new SystemConfig
                    {
                        ConfigKey = "collection.interval",
                        ConfigValue = "30",
                        Description = "Default collection interval in seconds",
                        Category = "Collection",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "collection.timeout",
                        ConfigValue = "10",
                        Description = "Collection timeout in seconds",
                        Category = "Collection",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "collection.retry.attempts",
                        ConfigValue = "3",
                        Description = "Number of retry attempts for failed collections",
                        Category = "Collection",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },

                    // Alert Settings
                    new SystemConfig
                    {
                        ConfigKey = "alert.email.enabled",
                        ConfigValue = "true",
                        Description = "Enable email alerts",
                        Category = "Alert",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "alert.sms.enabled",
                        ConfigValue = "false",
                        Description = "Enable SMS alerts",
                        Category = "Alert",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "alert.wechat.enabled",
                        ConfigValue = "false",
                        Description = "Enable WeChat alerts",
                        Category = "Alert",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },

                    // Data Retention
                    new SystemConfig
                    {
                        ConfigKey = "data.retention.days",
                        ConfigValue = "90",
                        Description = "Data retention period in days",
                        Category = "Data",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "log.retention.days",
                        ConfigValue = "30",
                        Description = "Log retention period in days",
                        Category = "Data",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },

                    // Authentication
                    new SystemConfig
                    {
                        ConfigKey = "auth.session.timeout",
                        ConfigValue = "60",
                        Description = "Session timeout in minutes",
                        Category = "Authentication",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "auth.max.login.attempts",
                        ConfigValue = "5",
                        Description = "Maximum login attempts before lockout",
                        Category = "Authentication",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },

                    // Performance
                    new SystemConfig
                    {
                        ConfigKey = "performance.cache.enabled",
                        ConfigValue = "true",
                        Description = "Enable caching",
                        Category = "Performance",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new SystemConfig
                    {
                        ConfigKey = "performance.cache.duration",
                        ConfigValue = "10",
                        Description = "Cache duration in minutes",
                        Category = "Performance",
                        IsActive = true,
                        IsDefault = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    }
                };

                await context.SystemConfigs.AddRangeAsync(configs);
                await context.SaveChangesAsync();
            }
        }

        private static async Task SeedAlarmRulesAsync(CNCBusinessDbContext context)
        {
            if (!await context.AlarmRules.AnyAsync())
            {
                var alarmRules = new List<AlarmRule>
                {
                    new AlarmRule
                    {
                        RuleName = "Device Offline",
                        DeviceId = null, // Apply to all devices
                        AlarmType = "DeviceOffline",
                        Condition = "device_offline",
                        Threshold = "",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new AlarmRule
                    {
                        RuleName = "High Temperature",
                        DeviceId = null, // Apply to all devices
                        AlarmType = "DeviceError",
                        Condition = "temperature > 100",
                        Threshold = "100",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new AlarmRule
                    {
                        RuleName = "Low Production Rate",
                        DeviceId = null, // Apply to all devices
                        AlarmType = "ProductionError",
                        Condition = "production_rate < 10",
                        Threshold = "10",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new AlarmRule
                    {
                        RuleName = "System Error",
                        DeviceId = null, // Apply to all devices
                        AlarmType = "SystemError",
                        Condition = "system_error > 0",
                        Threshold = "0",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    }
                };

                await context.AlarmRules.AddRangeAsync(alarmRules);
                await context.SaveChangesAsync();
            }
        }

        private static async Task SeedDeviceTemplatesAsync(CNCBusinessDbContext context)
        {
            if (!await context.CNCTemplates.AnyAsync())
            {
                var templates = new List<CNCBrandTemplate>
                {
                    new CNCBrandTemplate
                    {
                        TemplateName = "Fanuc Standard",
                        BrandName = "Fanuc",
                        Version = "1.0",
                        Description = "Standard template for Fanuc CNC machines",
                        TagsJson = @"[
                            {
                                ""systemTagId"": ""_io_status"",
                                ""deviceTagId"": ""_io_status"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Input/Output status""
                            },
                            {
                                ""systemTagId"": ""Tag5"",
                                ""deviceTagId"": ""Tag5"",
                                ""dataType"": ""string"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""NC program name""
                            },
                            {
                                ""systemTagId"": ""Tag8"",
                                ""deviceTagId"": ""Tag8"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Cumulative count""
                            },
                            {
                                ""systemTagId"": ""Tag9"",
                                ""deviceTagId"": ""Tag9"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Run status""
                            },
                            {
                                ""systemTagId"": ""Tag11"",
                                ""deviceTagId"": ""Tag11"",
                                ""dataType"": ""string"",
                                ""isRequired"": false,
                                ""validationRegex"": """",
                                ""description"": ""Operating mode""
                            },
                            {
                                ""systemTagId"": ""Tag14"",
                                ""deviceTagId"": ""Tag14"",
                                ""dataType"": ""int"",
                                ""isRequired"": false,
                                ""validationRegex"": """",
                                ""description"": ""Spindle override""
                            }
                        ]",
                        DataProcessingRulesJson = @"[
                            {
                                ""ruleName"": ""Production Calculation"",
                                ""condition"": ""Tag9 == 1 && Tag8 > 0"",
                                ""action"": ""calculate_production""
                            },
                            {
                                ""ruleName"": ""Status Update"",
                                ""condition"": ""_io_status == 1"",
                                ""action"": ""set_running""
                            }
                        ]",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new CNCBrandTemplate
                    {
                        TemplateName = "Mitsubishi Standard",
                        BrandName = "Mitsubishi",
                        Version = "1.0",
                        Description = "Standard template for Mitsubishi CNC machines",
                        TagsJson = @"[
                            {
                                ""systemTagId"": ""_io_status"",
                                ""deviceTagId"": ""_io_status"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Input/Output status""
                            },
                            {
                                ""systemTagId"": ""ProgramName"",
                                ""deviceTagId"": ""ProgramName"",
                                ""dataType"": ""string"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""NC program name""
                            },
                            {
                                ""systemTagId"": ""TotalCount"",
                                ""deviceTagId"": ""TotalCount"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Total production count""
                            },
                            {
                                ""systemTagId"": ""RunStatus"",
                                ""deviceTagId"": ""RunStatus"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Running status""
                            }
                        ]",
                        DataProcessingRulesJson = @"[
                            {
                                ""ruleName"": ""Production Calculation"",
                                ""condition"": ""RunStatus == 1 && TotalCount > 0"",
                                ""action"": ""calculate_production""
                            }
                        ]",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    },
                    new CNCBrandTemplate
                    {
                        TemplateName = "Siemens Standard",
                        BrandName = "Siemens",
                        Version = "1.0",
                        Description = "Standard template for Siemens CNC machines",
                        TagsJson = @"[
                            {
                                ""systemTagId"": ""ChannelState"",
                                ""deviceTagId"": ""ChannelState"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Channel state""
                            },
                            {
                                ""systemTagId"": ""ProgramName"",
                                ""deviceTagId"": ""ProgramName"",
                                ""dataType"": ""string"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Program name""
                            },
                            {
                                ""systemTagId"": ""PartCount"",
                                ""deviceTagId"": ""PartCount"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Part count""
                            },
                            {
                                ""systemTagId"": ""MachineState"",
                                ""deviceTagId"": ""MachineState"",
                                ""dataType"": ""int"",
                                ""isRequired"": true,
                                ""validationRegex"": """",
                                ""description"": ""Machine state""
                            }
                        ]",
                        DataProcessingRulesJson = @"[
                            {
                                ""ruleName"": ""Production Calculation"",
                                ""condition"": ""MachineState == 4 && PartCount > 0"",
                                ""action"": ""calculate_production""
                            }
                        ]",
                        IsActive = true,
                        CreatedAt = DateTime.Now,
                        UpdatedAt = DateTime.Now
                    }
                };

                await context.CNCTemplates.AddRangeAsync(templates);
                await context.SaveChangesAsync();
            }
        }
    }
}