-- ===========================================
-- SQL Server Setup Script for AccManager
-- Database: AccManager
-- Server: 172.20.235.176
-- ===========================================

-- Create Database
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'AccManager')
BEGIN
    CREATE DATABASE AccManager;
    PRINT 'Database AccManager created successfully.';
END
ELSE
BEGIN
    PRINT 'Database AccManager already exists.';
END
GO

USE AccManager;
GO

-- ===========================================
-- 1. CREATE USERS TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Users')
BEGIN
    CREATE TABLE Users (
        UserId INT PRIMARY KEY IDENTITY(1,1),
        Username NVARCHAR(50) UNIQUE NOT NULL,
        Password NVARCHAR(255) NOT NULL,
        Email NVARCHAR(100),
        FullName NVARCHAR(100),
        Role NVARCHAR(50) NOT NULL,
        Status NVARCHAR(20) DEFAULT 'Active',
        CreatedDate DATETIME DEFAULT GETDATE(),
        LastLogin DATETIME,
        IsActive BIT DEFAULT 1
    );
    PRINT 'Table Users created successfully.';
END

-- ===========================================
-- 2. CREATE APPLICATIONS TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Applications')
BEGIN
    CREATE TABLE Applications (
        AppId INT PRIMARY KEY IDENTITY(1,1),
        Name NVARCHAR(100) NOT NULL,
        Type NVARCHAR(50),
        Status NVARCHAR(20) DEFAULT 'online',
        Icon NVARCHAR(50),
        Description NVARCHAR(500),
        CreatedDate DATETIME DEFAULT GETDATE(),
        UpdatedDate DATETIME DEFAULT GETDATE()
    );
    PRINT 'Table Applications created successfully.';
END

-- ===========================================
-- 3. CREATE ACCOUNTS TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Accounts')
BEGIN
    CREATE TABLE Accounts (
        AccountId INT PRIMARY KEY IDENTITY(1,1),
        UserId INT NOT NULL,
        AppId INT NOT NULL,
        AccountUsername NVARCHAR(100),
        AccountPassword NVARCHAR(255),
        Email NVARCHAR(100),
        AccessLevel NVARCHAR(50),
        Status NVARCHAR(20) DEFAULT 'Active',
        Notes NVARCHAR(MAX),
        CreatedDate DATETIME DEFAULT GETDATE(),
        UpdatedDate DATETIME DEFAULT GETDATE(),
        FOREIGN KEY (UserId) REFERENCES Users(UserId) ON DELETE CASCADE,
        FOREIGN KEY (AppId) REFERENCES Applications(AppId) ON DELETE CASCADE
    );
    PRINT 'Table Accounts created successfully.';
END

-- ===========================================
-- 4. CREATE ASSET INVENTORY TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AssetInventory')
BEGIN
    CREATE TABLE AssetInventory (
        AssetId INT PRIMARY KEY IDENTITY(1,1),
        AssetCode NVARCHAR(100) NOT NULL UNIQUE,
        AssetName NVARCHAR(255) NOT NULL,
        Model NVARCHAR(255),
        SerialNumber NVARCHAR(100),
        Quantity INT NOT NULL DEFAULT 0,
        ImportInPeriod INT NOT NULL DEFAULT 0,
        ExportInPeriod INT NOT NULL DEFAULT 0,
        EndingBalance INT NOT NULL DEFAULT 0,
        Unit NVARCHAR(50),
        Department NVARCHAR(100),
        Project NVARCHAR(150),
        Location NVARCHAR(150),
        Custodian NVARCHAR(100),
        Borrower NVARCHAR(255),
        ExportedBy NVARCHAR(100),
        PurchaseDate DATE NULL,
        PurchasePrice DECIMAL(18,2) NULL,
        Status NVARCHAR(30) NOT NULL DEFAULT 'in_use',
        Notes NVARCHAR(MAX),
        CreatedBy INT NULL,
        CreatedDate DATETIME DEFAULT GETDATE(),
        UpdatedDate DATETIME DEFAULT GETDATE(),
        FOREIGN KEY (CreatedBy) REFERENCES Users(UserId) ON DELETE SET NULL
    );
    PRINT 'Table AssetInventory created successfully.';
END

IF COL_LENGTH('dbo.AssetInventory', 'Borrower') IS NULL
BEGIN
    ALTER TABLE AssetInventory ADD Borrower NVARCHAR(255) NULL;
END

IF COL_LENGTH('dbo.AssetInventory', 'ExportedBy') IS NULL
BEGIN
    ALTER TABLE AssetInventory ADD ExportedBy NVARCHAR(100) NULL;
END

-- ===========================================
-- 5. CREATE ASSET DEPARTMENTS TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AssetDepartments')
BEGIN
    CREATE TABLE AssetDepartments (
        DepartmentId INT PRIMARY KEY IDENTITY(1,1),
        DepartmentName NVARCHAR(100) NOT NULL,
        CreatedDate DATETIME DEFAULT GETDATE(),
        UpdatedDate DATETIME DEFAULT GETDATE()
    );
    PRINT 'Table AssetDepartments created successfully.';
END

;WITH SourceDepartments AS (
    SELECT DISTINCT LTRIM(RTRIM(Department)) AS DepartmentName
    FROM AssetInventory
    WHERE Department IS NOT NULL
      AND LTRIM(RTRIM(Department)) <> ''
)
INSERT INTO AssetDepartments (DepartmentName)
SELECT source.DepartmentName
FROM SourceDepartments source
WHERE NOT EXISTS (
    SELECT 1
    FROM AssetDepartments target
    WHERE LOWER(LTRIM(RTRIM(target.DepartmentName))) = LOWER(source.DepartmentName)
);

-- ===========================================
-- 6. CREATE ASSET PROJECTS TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AssetProjects')
BEGIN
    CREATE TABLE AssetProjects (
        ProjectId INT PRIMARY KEY IDENTITY(1,1),
        ProjectName NVARCHAR(150) NOT NULL,
        CreatedDate DATETIME DEFAULT GETDATE(),
        UpdatedDate DATETIME DEFAULT GETDATE()
    );
    PRINT 'Table AssetProjects created successfully.';
END

-- ===========================================
-- 7. CREATE ASSET BORROW REQUESTS TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AssetBorrowRequests')
BEGIN
    CREATE TABLE AssetBorrowRequests (
        BorrowId INT PRIMARY KEY IDENTITY(1,1),
        AssetId INT NOT NULL,
        RequestType NVARCHAR(20) NOT NULL DEFAULT 'borrow',
        RequestStatus NVARCHAR(20) NOT NULL DEFAULT 'pending',
        BorrowerName NVARCHAR(100) NOT NULL,
        BorrowQuantity INT NOT NULL DEFAULT 1,
        Unit NVARCHAR(50),
        BorrowDate DATE NOT NULL DEFAULT CAST(GETDATE() AS DATE),
        RequestNote NVARCHAR(500) NULL,
        RejectReason NVARCHAR(1000) NULL,
        CreatedBy INT NULL,
        ProcessedBy INT NULL,
        ProcessedByName NVARCHAR(100) NULL,
        ProcessedDate DATETIME NULL,
        CreatedDate DATETIME DEFAULT GETDATE(),
        UpdatedDate DATETIME DEFAULT GETDATE(),
        FOREIGN KEY (AssetId) REFERENCES AssetInventory(AssetId) ON DELETE CASCADE,
        FOREIGN KEY (CreatedBy) REFERENCES Users(UserId) ON DELETE SET NULL,
        FOREIGN KEY (ProcessedBy) REFERENCES Users(UserId) ON DELETE SET NULL
    );
    PRINT 'Table AssetBorrowRequests created successfully.';
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'Unit') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD Unit NVARCHAR(50) NULL;
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'BorrowDate') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD BorrowDate DATE NOT NULL CONSTRAINT DF_AssetBorrowRequests_BorrowDate DEFAULT(CAST(GETDATE() AS DATE));
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'UpdatedDate') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD UpdatedDate DATETIME NOT NULL CONSTRAINT DF_AssetBorrowRequests_UpdatedDate DEFAULT(GETDATE());
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'RequestType') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD RequestType NVARCHAR(20) NOT NULL CONSTRAINT DF_AssetBorrowRequests_RequestType DEFAULT('borrow');
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'RequestStatus') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD RequestStatus NVARCHAR(20) NOT NULL CONSTRAINT DF_AssetBorrowRequests_RequestStatus DEFAULT('approved');
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'RequestNote') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD RequestNote NVARCHAR(500) NULL;
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'RejectReason') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD RejectReason NVARCHAR(1000) NULL;
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'ProcessedBy') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD ProcessedBy INT NULL;
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'ProcessedByName') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD ProcessedByName NVARCHAR(100) NULL;
END

IF COL_LENGTH('dbo.AssetBorrowRequests', 'ProcessedDate') IS NULL
BEGIN
    ALTER TABLE AssetBorrowRequests ADD ProcessedDate DATETIME NULL;
END

IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = 'FK_AssetBorrowRequests_ProcessedBy')
BEGIN
    ALTER TABLE AssetBorrowRequests
    ADD CONSTRAINT FK_AssetBorrowRequests_ProcessedBy
    FOREIGN KEY (ProcessedBy) REFERENCES Users(UserId) ON DELETE SET NULL;
END

UPDATE AssetBorrowRequests
SET RequestType = ISNULL(NULLIF(LTRIM(RTRIM(RequestType)), ''), 'borrow');

UPDATE AssetBorrowRequests
SET RequestStatus = ISNULL(NULLIF(LTRIM(RTRIM(RequestStatus)), ''), 'approved');

-- ===========================================
-- 8. CREATE ASSET EXPORT HISTORY TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AssetExportHistory')
BEGIN
    CREATE TABLE AssetExportHistory (
        ExportHistoryId INT PRIMARY KEY IDENTITY(1,1),
        AssetId INT NOT NULL,
        AssetCode NVARCHAR(100) NOT NULL,
        AssetName NVARCHAR(255) NOT NULL,
        ExportQuantity INT NOT NULL DEFAULT 1,
        ProjectName NVARCHAR(150) NULL,
        CustodianName NVARCHAR(100) NOT NULL,
        ExportedByName NVARCHAR(100) NOT NULL,
        ExportNote NVARCHAR(1000) NULL,
        CreatedBy INT NULL,
        ExportedDate DATETIME NOT NULL DEFAULT GETDATE(),
        CreatedDate DATETIME NOT NULL DEFAULT GETDATE(),
        UpdatedDate DATETIME NOT NULL DEFAULT GETDATE(),
        FOREIGN KEY (AssetId) REFERENCES AssetInventory(AssetId) ON DELETE CASCADE
    );
    PRINT 'Table AssetExportHistory created successfully.';
END

IF COL_LENGTH('dbo.AssetExportHistory', 'AssetCode') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD AssetCode NVARCHAR(100) NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'AssetName') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD AssetName NVARCHAR(255) NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'ExportQuantity') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD ExportQuantity INT NOT NULL CONSTRAINT DF_AssetExportHistory_ExportQuantity DEFAULT(1);
END

IF COL_LENGTH('dbo.AssetExportHistory', 'ProjectName') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD ProjectName NVARCHAR(150) NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'CustodianName') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD CustodianName NVARCHAR(100) NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'ExportedByName') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD ExportedByName NVARCHAR(100) NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'ExportNote') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD ExportNote NVARCHAR(1000) NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'CreatedBy') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD CreatedBy INT NULL;
END

IF COL_LENGTH('dbo.AssetExportHistory', 'ExportedDate') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD ExportedDate DATETIME NOT NULL CONSTRAINT DF_AssetExportHistory_ExportedDate DEFAULT(GETDATE());
END

IF COL_LENGTH('dbo.AssetExportHistory', 'CreatedDate') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD CreatedDate DATETIME NOT NULL CONSTRAINT DF_AssetExportHistory_CreatedDate DEFAULT(GETDATE());
END

IF COL_LENGTH('dbo.AssetExportHistory', 'UpdatedDate') IS NULL
BEGIN
    ALTER TABLE AssetExportHistory ADD UpdatedDate DATETIME NOT NULL CONSTRAINT DF_AssetExportHistory_UpdatedDate DEFAULT(GETDATE());
END

IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = 'FK_AssetExportHistory_CreatedBy')
   AND COL_LENGTH('dbo.AssetExportHistory', 'CreatedBy') IS NOT NULL
BEGIN
    IF NOT EXISTS (
        SELECT 1
        FROM sys.foreign_key_columns fkc
        INNER JOIN sys.columns c
            ON c.object_id = fkc.parent_object_id
            AND c.column_id = fkc.parent_column_id
        WHERE fkc.parent_object_id = OBJECT_ID('dbo.AssetExportHistory')
          AND c.name = 'CreatedBy'
    )
    BEGIN
        ALTER TABLE AssetExportHistory
        ADD CONSTRAINT FK_AssetExportHistory_CreatedBy
        FOREIGN KEY (CreatedBy) REFERENCES Users(UserId) ON DELETE SET NULL;
    END
END

-- ===========================================
-- 9. CREATE AUDIT LOG TABLE
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'AuditLog')
BEGIN
    CREATE TABLE AuditLog (
        LogId INT PRIMARY KEY IDENTITY(1,1),
        UserId INT,
        Action NVARCHAR(50),
        TableName NVARCHAR(50),
        RecordId INT,
        OldValue NVARCHAR(MAX),
        NewValue NVARCHAR(MAX),
        Timestamp DATETIME DEFAULT GETDATE(),
        FOREIGN KEY (UserId) REFERENCES Users(UserId)
    );
    PRINT 'Table AuditLog created successfully.';
END

-- ===========================================
-- 10. CREATE INDEXES
-- ===========================================
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Users_Username')
BEGIN
    CREATE INDEX IX_Users_Username ON Users(Username);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Accounts_UserId')
BEGIN
    CREATE INDEX IX_Accounts_UserId ON Accounts(UserId);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Accounts_AppId')
BEGIN
    CREATE INDEX IX_Accounts_AppId ON Accounts(AppId);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetInventory_AssetCode')
BEGIN
    CREATE INDEX IX_AssetInventory_AssetCode ON AssetInventory(AssetCode);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetInventory_Status')
BEGIN
    CREATE INDEX IX_AssetInventory_Status ON AssetInventory(Status);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetInventory_Department')
BEGIN
    CREATE INDEX IX_AssetInventory_Department ON AssetInventory(Department);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'UX_AssetDepartments_DepartmentName')
BEGIN
    CREATE UNIQUE INDEX UX_AssetDepartments_DepartmentName ON AssetDepartments(DepartmentName);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'UX_AssetProjects_ProjectName')
BEGIN
    CREATE UNIQUE INDEX UX_AssetProjects_ProjectName ON AssetProjects(ProjectName);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetBorrowRequests_AssetId')
BEGIN
    CREATE INDEX IX_AssetBorrowRequests_AssetId ON AssetBorrowRequests(AssetId);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetBorrowRequests_BorrowDate')
BEGIN
    CREATE INDEX IX_AssetBorrowRequests_BorrowDate ON AssetBorrowRequests(BorrowDate DESC);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetBorrowRequests_RequestStatus')
BEGIN
    CREATE INDEX IX_AssetBorrowRequests_RequestStatus ON AssetBorrowRequests(RequestStatus);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetBorrowRequests_RequestType')
BEGIN
    CREATE INDEX IX_AssetBorrowRequests_RequestType ON AssetBorrowRequests(RequestType);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetExportHistory_AssetId')
BEGIN
    CREATE INDEX IX_AssetExportHistory_AssetId ON AssetExportHistory(AssetId);
END

IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_AssetExportHistory_ExportedDate')
BEGIN
    CREATE INDEX IX_AssetExportHistory_ExportedDate ON AssetExportHistory(ExportedDate DESC);
END

PRINT 'Indexes created successfully.';

-- ===========================================
-- 11. INSERT INITIAL DATA
-- ===========================================

-- Check if admin user exists
IF NOT EXISTS (SELECT * FROM Users WHERE Username = 'admin')
BEGIN
    INSERT INTO Users (Username, Password, Email, FullName, Role, Status, IsActive)
    VALUES ('admin', 'admin', 'admin@accmanager.local', 'Administrator', 'admin', 'Active', 1);
    PRINT 'Admin user created: Username=admin, Password=[REDACTED]
END

-- Insert sample applications
IF (SELECT COUNT(*) FROM Applications) = 0
BEGIN
    INSERT INTO Applications (Name, Type, Status, Icon, Description)
    VALUES 
        ('AWS', 'Cloud', 'online', 'cloud', 'Amazon Web Services - Cloud Computing'),
        ('GitHub', 'VCS', 'online', 'code', 'GitHub - Version Control System'),
        ('Google Workspace', 'Collaboration', 'online', 'mail', 'Google Workspace - Email and Collaboration'),
        ('Nginx Proxy', 'Infra', 'offline', 'dns', 'Nginx - Web Server and Reverse Proxy');
    PRINT 'Sample applications inserted successfully.';
END

-- ===========================================
-- 12. DISPLAY DATABASE INFORMATION
-- ===========================================
PRINT '';
PRINT '========================================';
PRINT 'DATABASE SETUP COMPLETED SUCCESSFULLY';
PRINT '========================================';
PRINT '';
PRINT 'Database Name: AccManager';
PRINT '';
PRINT 'Tables created:';
SELECT '  - ' + name AS TableName FROM sys.tables ORDER BY name;
PRINT '';
PRINT 'Users in system:';
SELECT '  Username: ' + Username + ' | Role: ' + Role + ' | Status: ' + Status AS UserInfo FROM Users;
PRINT '';
PRINT 'Applications available:';
SELECT '  - ' + Name + ' (' + Type + ') - ' + Status AS AppInfo FROM Applications ORDER BY Name;
PRINT '';
PRINT 'Login Credentials:';
PRINT '  Username: admin';
PRINT '  Password: [REDACTED]
PRINT '  Role: admin';
PRINT '';
PRINT '========================================';
