-- Asset alert and summary views (run from patch-assets-amc-insurance.sql or standalone)

DROP VIEW IF EXISTS v_asset_expiry_alerts CASCADE;
DROP VIEW IF EXISTS v_asset_next_service CASCADE;
DROP VIEW IF EXISTS v_assets CASCADE;

CREATE VIEW v_asset_expiry_alerts AS
  SELECT
    a.id AS asset_id,
    a.asset_code,
    a.asset_name,
    ac_cat.name AS category_name,
    p.name AS plant_name,
    d.name AS department_name,
    'AMC'::text AS alert_type,
    amc.id AS reference_id,
    amc.contract_no AS reference_no,
    v.vendor_name AS party_name,
    amc.end_date AS expiry_date,
    (amc.end_date - CURRENT_DATE) AS days_remaining,
    CASE
      WHEN (amc.end_date - CURRENT_DATE) <= 0 THEN 'EXPIRED'
      WHEN (amc.end_date - CURRENT_DATE) <= 30 THEN 'CRITICAL'
      WHEN (amc.end_date - CURRENT_DATE) <= 60 THEN 'WARNING'
      WHEN (amc.end_date - CURRENT_DATE) <= 90 THEN 'INFO'
    END AS alert_level
  FROM asset_amc_contracts amc
  JOIN assets a ON a.id = amc.asset_id
  JOIN asset_categories ac_cat ON ac_cat.id = a.asset_category_id
  JOIN plants p ON p.id = a.plant_id
  LEFT JOIN departments d ON d.id = a.department_id
  LEFT JOIN vendors v ON v.id = amc.vendor_id
  WHERE amc.is_active = TRUE AND amc.deleted_at IS NULL AND a.deleted_at IS NULL
    AND (amc.end_date - CURRENT_DATE) <= 90

UNION ALL

  SELECT
    a.id, a.asset_code, a.asset_name, ac_cat.name, p.name, d.name,
    'INSURANCE'::text, ins.id, ins.policy_no, ins.insurer_name,
    ins.policy_end_date, (ins.policy_end_date - CURRENT_DATE),
    CASE
      WHEN (ins.policy_end_date - CURRENT_DATE) <= 0 THEN 'EXPIRED'
      WHEN (ins.policy_end_date - CURRENT_DATE) <= 30 THEN 'CRITICAL'
      WHEN (ins.policy_end_date - CURRENT_DATE) <= 60 THEN 'WARNING'
      WHEN (ins.policy_end_date - CURRENT_DATE) <= 90 THEN 'INFO'
    END
  FROM asset_insurance_policies ins
  JOIN assets a ON a.id = ins.asset_id
  JOIN asset_categories ac_cat ON ac_cat.id = a.asset_category_id
  JOIN plants p ON p.id = a.plant_id
  LEFT JOIN departments d ON d.id = a.department_id
  WHERE ins.is_active = TRUE AND ins.deleted_at IS NULL AND a.deleted_at IS NULL
    AND (ins.policy_end_date - CURRENT_DATE) <= 90

UNION ALL

  SELECT
    a.id, a.asset_code, a.asset_name, ac_cat.name, p.name, d.name,
    'WARRANTY'::text, a.id, a.asset_code, 'Manufacturer Warranty'::varchar,
    a.warranty_expiry_date, (a.warranty_expiry_date - CURRENT_DATE),
    CASE
      WHEN (a.warranty_expiry_date - CURRENT_DATE) <= 0 THEN 'EXPIRED'
      WHEN (a.warranty_expiry_date - CURRENT_DATE) <= 30 THEN 'CRITICAL'
      WHEN (a.warranty_expiry_date - CURRENT_DATE) <= 60 THEN 'WARNING'
      WHEN (a.warranty_expiry_date - CURRENT_DATE) <= 90 THEN 'INFO'
    END
  FROM assets a
  JOIN asset_categories ac_cat ON ac_cat.id = a.asset_category_id
  JOIN plants p ON p.id = a.plant_id
  LEFT JOIN departments d ON d.id = a.department_id
  WHERE a.warranty_expiry_date IS NOT NULL AND a.deleted_at IS NULL
    AND (a.warranty_expiry_date - CURRENT_DATE) <= 90;

CREATE VIEW v_asset_next_service AS
SELECT
  a.id AS asset_id,
  a.asset_code,
  a.asset_name,
  ac_cat.name AS category_name,
  p.name AS plant_name,
  d.name AS department_name,
  sv.id AS last_visit_id,
  sv.visit_date AS last_service_date,
  sv.visit_type AS last_visit_type,
  sv.next_service_date,
  (sv.next_service_date - CURRENT_DATE) AS days_to_next_service,
  CASE
    WHEN sv.next_service_date < CURRENT_DATE THEN 'OVERDUE'
    WHEN (sv.next_service_date - CURRENT_DATE) <= 7 THEN 'DUE_THIS_WEEK'
    WHEN (sv.next_service_date - CURRENT_DATE) <= 30 THEN 'DUE_THIS_MONTH'
    ELSE 'UPCOMING'
  END AS service_status,
  v.vendor_name AS service_vendor,
  amc.contract_no AS amc_contract_no,
  amc.end_date AS amc_end_date
FROM assets a
JOIN asset_categories ac_cat ON ac_cat.id = a.asset_category_id
JOIN plants p ON p.id = a.plant_id
LEFT JOIN departments d ON d.id = a.department_id
JOIN LATERAL (
  SELECT * FROM asset_service_visits
  WHERE asset_id = a.id AND deleted_at IS NULL AND next_service_date IS NOT NULL
  ORDER BY visit_date DESC
  LIMIT 1
) sv ON TRUE
LEFT JOIN vendors v ON v.id = sv.vendor_id
LEFT JOIN asset_amc_contracts amc
  ON amc.asset_id = a.id AND amc.is_active = TRUE AND amc.deleted_at IS NULL
WHERE a.deleted_at IS NULL AND a.status NOT IN ('DISPOSED','SCRAPPED');

CREATE VIEW v_assets AS
SELECT
  a.id,
  a.asset_code,
  a.asset_name,
  ac.name AS category_name,
  a.brand_model,
  a.serial_number,
  a.status,
  a.condition,
  a.purchase_date,
  a.purchase_cost,
  a.warranty_expiry_date,
  p.name AS plant_name,
  d.name AS department_name,
  w.name AS warehouse_name,
  a.location_detail,
  u.full_name AS assigned_to,
  v.vendor_name AS supplier,
  a.qr_code_value,
  amc.contract_no AS amc_contract_no,
  amc.end_date AS amc_expiry_date,
  amc.contract_type AS amc_type,
  amcv.vendor_name AS amc_vendor,
  (amc.end_date - CURRENT_DATE) AS amc_days_remaining,
  ins.policy_no AS insurance_policy_no,
  ins.policy_end_date AS insurance_expiry_date,
  ins.insurer_name,
  ins.sum_insured,
  (ins.policy_end_date - CURRENT_DATE) AS insurance_days_remaining,
  lsv.visit_date AS last_service_date,
  lsv.next_service_date,
  (lsv.next_service_date - CURRENT_DATE) AS service_due_in_days,
  a.created_at
FROM assets a
JOIN asset_categories ac ON ac.id = a.asset_category_id
JOIN plants p ON p.id = a.plant_id
LEFT JOIN departments d ON d.id = a.department_id
LEFT JOIN warehouses w ON w.id = a.warehouse_id
LEFT JOIN users u ON u.id = a.assigned_to_user_id
LEFT JOIN vendors v ON v.id = a.vendor_id
LEFT JOIN asset_amc_contracts amc
  ON amc.asset_id = a.id AND amc.is_active = TRUE AND amc.deleted_at IS NULL
LEFT JOIN vendors amcv ON amcv.id = amc.vendor_id
LEFT JOIN asset_insurance_policies ins
  ON ins.asset_id = a.id AND ins.is_active = TRUE AND ins.deleted_at IS NULL
LEFT JOIN LATERAL (
  SELECT visit_date, next_service_date
  FROM asset_service_visits
  WHERE asset_id = a.id AND deleted_at IS NULL
  ORDER BY visit_date DESC LIMIT 1
) lsv ON TRUE
WHERE a.deleted_at IS NULL;
